﻿using BackupContracts.Tasks;
using BackupManager.Storage;
using BackupManager.Tasks.Data;
using Microsoft.WindowsAzure.Storage;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;

namespace BackupManager.Tasks
{
    public class TaskProvider
    {
        private const string _PartiotionKey = "tasks";
        private CloudStorageAccount _StorageAccount;

        public TaskProvider(CloudStorageAccount storageAccount)
        {
            _StorageAccount = storageAccount;
        }

        public void UpsertTask(Task task)
        {
            var taskEntity = new TaskEntity()
            {
                Name = task.Name,
                PartitionKey = _PartiotionKey,
                RowKey = task.Id,
                Enabled = task.Enabled,
                Data = Serializer.Serialize(task),
                LastExecution = TableStorageHelper.NullableDateTimeOffsetToDateTime(task.LastExecution),
                LastExecutionStart = TableStorageHelper.NullableDateTimeOffsetToDateTime(task.LastExecutionStart),
            };
            var entityContext = new TaskEntityContext(_StorageAccount.CreateCloudTableClient());
            entityContext.Upsert(taskEntity);
        }

        public void DeleteTask(string serverId)
        {
            var entityContext = new TaskEntityContext(_StorageAccount.CreateCloudTableClient());
            entityContext.Delete(_PartiotionKey, serverId);
        }

        public List<Task> ListTasks()
        {
            var entityContext = new TaskEntityContext(_StorageAccount.CreateCloudTableClient());
            return (from entity in entityContext.CreateQuery().ToList()
                    select EntityToModel(entity)).ToList();
        }

        private static Task EntityToModel(TaskEntity entity)
        {
            var task = Serializer.Deserialize<Task>(entity.Data);
            task.Name = entity.Name;
            task.Id = entity.RowKey;
            task.Enabled = entity.Enabled;
            task.LastExecution = TableStorageHelper.DateTimeToNullableDateTimeOffset(entity.LastExecution);
            task.LastExecutionStart = TableStorageHelper.DateTimeToNullableDateTimeOffset(entity.LastExecutionStart);
            return task;
        }

        public List<MaintenanceTask> ListMaintenanceTasks()
        {
            var entityContext = new MaintenanceTaskEntityContext(_StorageAccount.CreateCloudTableClient());
            return (from entity in entityContext.CreateQuery().ToList()
                    select EntityToModel(entity)).ToList();
        }

        private MaintenanceTask EntityToModel(MaintenanceTaskEntity entity)
        {
            var task = new MaintenanceTask();
            task.Name = entity.Name;
            task.Id = entity.RowKey;
            task.Enabled = entity.Enabled;
            task.RepeatEveryXMinutes = entity.RepeatEveryXMinutes;
            task.LastExecution = TableStorageHelper.DateTimeToNullableDateTimeOffset(entity.LastExecution);
            task.LastExecutionStart = TableStorageHelper.DateTimeToNullableDateTimeOffset(entity.LastExecutionStart);
            return task;
        }

        public void UpsertTask(MaintenanceTask maintenanceTask)
        {
            var taskEntity = new MaintenanceTaskEntity()
            {
                Name = maintenanceTask.Name,
                PartitionKey = _PartiotionKey,
                RowKey = maintenanceTask.Id,
                Enabled = maintenanceTask.Enabled,
                LastExecution = TableStorageHelper.NullableDateTimeOffsetToDateTime(maintenanceTask.LastExecution),
                LastExecutionStart = TableStorageHelper.NullableDateTimeOffsetToDateTime(maintenanceTask.LastExecutionStart),
                RepeatEveryXMinutes = maintenanceTask.RepeatEveryXMinutes,
            };
            var entityContext = new MaintenanceTaskEntityContext(_StorageAccount.CreateCloudTableClient());
            entityContext.Upsert(taskEntity);
        }

        public void RefreshTask(MaintenanceTask maintenanceTask)
        {

        }

        public void RefreshTask(Task task)
        {

        }
    }
}
